package com.starinside.wp.service.impl;

import com.alibaba.fastjson.JSON;
import com.starinside.wp.domain.Classes;
import com.starinside.wp.domain.course.CourseAppendix;
import com.starinside.wp.domain.course.CourseTool;
import com.starinside.wp.domain.course.VendorCourse;
import com.starinside.wp.domain.course.VendorCourseContent;
import com.starinside.wp.foundation.exception.BusinessException;
import com.starinside.wp.foundation.query.base.PagerQuery;
import com.starinside.wp.repository.*;
import com.starinside.wp.service.VendorCourseService;
import com.tuo51.foudation.utils.CopyUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.InputStream;
import java.time.Instant;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class VendorCourseServiceImpl implements VendorCourseService {

    @Autowired
    private VendorCourseRepository vendorCourseRepository;

    @Autowired
    private BaseNativeSqlRepository baseNativeSqlRepository;

    @Autowired
    private ClassesRepository classesRepository;

    @Autowired
    private VendorCourseContentRepository vendorCourseContentRepository;


    @Autowired
    private CourseAppendixRepository courseAppendixRepository;

    //分类
    private static  final String  KC_SORT = "kc_sort";
    //年龄
    private static  final String  KC_AGE = "kc_age";
    @Override
    public VendorCourse getVendorCourse(String courseId) {
        return vendorCourseRepository.getOne(courseId);
    }

    @Override
    public VendorCourse addVendorCourse(String title, String author, String content, String attachments, String tools, String persistentTemplateId, int indexInPackage, String tags, String dimensions, String guideVideo) {
        VendorCourse vendorCourse = new VendorCourse();
        vendorCourse.setTitle(title);
        vendorCourse.setAuthor(author);
        vendorCourse.setComment(content);
        vendorCourse.setAttachments(attachments);
        vendorCourse.setTools(tools);
        vendorCourse.setContentTemplateId(persistentTemplateId);
        vendorCourse.setIndexInPackage(indexInPackage);
        vendorCourse.setTags(tags);
        vendorCourse.setDimensions(dimensions);
        vendorCourse.setGuideVideo(guideVideo);
        vendorCourseRepository.save(vendorCourse);
        return vendorCourse;
    }

    @Override
    public Page<VendorCourse> getVendorList(String name, PagerQuery pagerQuery) {
        Specification<VendorCourse> specification = new Specification<VendorCourse>() {
            @Override
            public Predicate toPredicate(Root<VendorCourse> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (StringUtils.isNotBlank(name))
                    predicates.add(criteriaBuilder.and(criteriaBuilder.like(root.get("title"), name)));
                    query.where(predicates.toArray(new Predicate[predicates.size()]));
                    query.orderBy(criteriaBuilder.desc(root.get("created")));
                    return query.getRestriction();
            }
        };
        Page<VendorCourse> liveRecordPage = vendorCourseRepository.findAll(specification, PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize()));
        return liveRecordPage;
    }


    @Override
    public Page<VendorCourse> packageIdByCourseList(String packageId, PagerQuery pagerQuery) {
        Specification<VendorCourse> specification = new Specification<VendorCourse>() {
            @Override
            public Predicate toPredicate(Root<VendorCourse> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (StringUtils.isNotBlank(packageId))
                    predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("course_package_id"), packageId)));
                query.where(predicates.toArray(new Predicate[predicates.size()]));
                query.orderBy(criteriaBuilder.desc(root.get("created")));
                return query.getRestriction();
            }
        };
        Page<VendorCourse> liveRecordPage = vendorCourseRepository.findAll(specification, PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize()));
        return liveRecordPage;
    }


    @Override
    public Page<VendorCourse> packageIdInCourseList(List<String> packageIds, PagerQuery pagerQuery) {
        Specification<VendorCourse> specification = new Specification<VendorCourse>() {
            @Override
            public Predicate toPredicate(Root<VendorCourse> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                CriteriaBuilder.In<Object> p4 = criteriaBuilder.in(root.get("coursePackageId"));
                for (String id : packageIds){
                    p4.value(id);
                }

                Predicate p3 = criteriaBuilder.equal(root.get("deleted"), 0);
                Predicate p1 = criteriaBuilder.and( p3, p4);
                query.where(p1);
                query.orderBy(criteriaBuilder.asc(root.get("indexInPackage")));
                return query.getRestriction();
            }
        };
        Page<VendorCourse> liveRecordPage = vendorCourseRepository.findAll(specification, PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize()));
        return liveRecordPage;
    }


    @Override
    public Page<VendorCourse> courseListV2(String title, String age, String week, String face, Integer type, PagerQuery pagerQuery) {
        Specification<VendorCourse> specification = new Specification<VendorCourse>() {
            @Override
            public Predicate toPredicate(Root<VendorCourse> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

                List<Predicate> predicates = new ArrayList<>();
                if (Objects.nonNull(type) ) {
                    predicates.add(criteriaBuilder.equal(root.get("type"), type));
                }
                if (Objects.nonNull(age) && !StringUtils.equals("",age)) {
                    String[] ages = age.split("-");
                    if (ages.length>1){
                        Integer ageLow = Integer.valueOf(ages[0]);
                        Integer ageHigh = Integer.valueOf(ages[1]);
                        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ageLow"), ageLow));
                        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ageHigh"), ageHigh));
                        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("ageLow"), ageHigh));
                    }else {
                        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("ageLow"), Integer.valueOf(age)));
                        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("ageHigh"), Integer.valueOf(age)));
                    }
                }
                if (Objects.nonNull(title)&& !StringUtils.equals("",title)) {
                    predicates.add(criteriaBuilder.and(criteriaBuilder.like(root.get("title"),"%" + title + "%")));
                }
                if (Objects.nonNull(week)&& !StringUtils.equals("",week)) {
                    predicates.add(criteriaBuilder.and(criteriaBuilder.like(root.get("details"),"%" + week+"\"" + "%")));
                }

                if (Objects.nonNull(face)&& !StringUtils.equals("",face)) {
                    predicates.add(criteriaBuilder.and(criteriaBuilder.like(root.get("details"),"%" + face +"\""+ "%")));
                }

                predicates.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("deleted"), 0)));
                query.where(predicates.toArray(new Predicate[predicates.size()]));
                query.orderBy(criteriaBuilder.asc(root.get("indexInPackage")));
                return query.getRestriction();
            }
        };
        Page<VendorCourse> liveRecordPage = vendorCourseRepository.findAll(specification, PageRequest.of(pagerQuery.getPageNum(), pagerQuery.getPageSize()));
        return liveRecordPage;
    }


    @Override
    public List<VendorCourseContent> findByCourseId(String courseId) {
        return vendorCourseContentRepository.findByCourseIdOrderByOrderNumAsc(courseId);
    }

    @Override
    public List<VendorCourseContent> findByCourseId(String courseId, Integer detailsType) {
        return vendorCourseContentRepository.findByCourseIdAndDetailsTypeOrderByOrderNumAsc(courseId,detailsType);
    }

    @Override
    public List<VendorCourseContent> findByVendorPackageId(String vendorPackageId) {
        return vendorCourseContentRepository.findByVendorPackageIdOrderByOrderNumAsc(vendorPackageId);
    }

    @Override
    public List<VendorCourseContent> findVendorPackageId(String  courseId) {
        return vendorCourseContentRepository.findVendorPackageIdOrderByOrderNumAsc( courseId);
    }

    @Override
    public List<CourseAppendix> courseAppendix() {
        return courseAppendixRepository.findAll();
    }
}
